{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Otto商品分类——线性SVM\n",
    "\n",
    "我们以Kaggle 2015年举办的Otto Group Product Classification Challenge竞赛数据为例，分别调用\n",
    "缺省参数LinearSVC、\n",
    "LinearSVC + CV进行参数调优（手动实现循环）。\n",
    "\n",
    "Otto数据集是著名电商Otto提供的一个多类商品分类问题，类别数=9. 每个样本有93维数值型特征（整数，表示某种事件发生的次数，已经进行过脱敏处理）。 竞赛官网：https://www.kaggle.com/c/otto-group-product-classification-challenge/data\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 首先 import 必要的模块\n",
    "import pandas as pd \n",
    "import numpy as np\n",
    "\n",
    "#竞赛的评价指标为logloss，但LinearSVC不支持概率\n",
    "#所以在这个例子中我们用正确率accuracy_score作为模型选择的度量\n",
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.metrics import confusion_matrix\n",
    "\n",
    "from matplotlib import pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(61878, 95)\n",
      "(61878, 95)\n"
     ]
    }
   ],
   "source": [
    "# 读取数据\n",
    "# path to where the data lies\n",
    "dpath = './data/'\n",
    "\n",
    "# 采用原始特征 + tf_idf特征\n",
    "#原始特征 + tf_idf特征对线性SVM训练还是很快，RBF核已慢得不行\n",
    "# RBF核只用tf_idf特征\n",
    "train1 = pd.read_csv(dpath +\"Otto_FE_train_org.csv\")\n",
    "train2 = pd.read_csv(dpath +\"Otto_FE_train_tfidf.csv\")\n",
    "#train = pd.read_csv(dpath +\"Otto_FE_train_tfidf.csv\")\n",
    "\n",
    "print (train1.shape)\n",
    "print (train2.shape)\n",
    "\n",
    "#去掉多余的id\n",
    "train2 = train2.drop([\"id\",\"target\"], axis=1)\n",
    "train =  pd.concat([train1, train2], axis = 1, ignore_index=False)\n",
    "train.head()\n",
    "\n",
    "del train1\n",
    "del train2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(61878, 188)\n"
     ]
    }
   ],
   "source": [
    "#train.info()\n",
    "print (train.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将类别字符串变成数字\n",
    "# drop ids and get labels\n",
    "y_train = train['target']   #形式为Class_x\n",
    "X_train = train.drop([\"id\", \"target\"], axis=1)\n",
    "\n",
    "#保存特征名字以备后用（可视化）\n",
    "feat_names = X_train.columns \n",
    "\n",
    "#sklearn的学习器大多之一稀疏数据输入，模型训练会快很多\n",
    "from scipy.sparse import csr_matrix\n",
    "X_train = csr_matrix(X_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 训练样本6w+，交叉验证太慢，用train_test_split估计模型性能\n",
    "# SVM对大样本数据集支持不太好\n",
    "from sklearn.model_selection import train_test_split\n",
    "X_train_part, X_val, y_train_part, y_val = train_test_split(X_train, y_train, train_size = 0.16161,random_state = 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(10000, 186)\n"
     ]
    }
   ],
   "source": [
    "print (X_train_part.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 默认参数的 SVC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.svm import LinearSVC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,\n",
       "     intercept_scaling=1, loss='squared_hinge', max_iter=1000,\n",
       "     multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,\n",
       "     verbose=0)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#LinearSVC不能得到每类的概率（只有predict函数，没有predict_proba函数），在Otto数据集要求输出每类的概率，这里只是示意SVM的使用方法\n",
    "#https://xacecask2.gitbooks.io/scikit-learn-user-guide-chinese-version/content/sec1.4.html\n",
    "#1.4.1.2. 得分与概率\n",
    "#1. 生成学习器实例\n",
    "SVC1 = LinearSVC()\n",
    "\n",
    "#2. 模型训练\n",
    "SVC1.fit(X_train_part, y_train_part)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "accuracy is:  0.7596283588418983\n",
      "Classification report for classifier LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,\n",
      "     intercept_scaling=1, loss='squared_hinge', max_iter=1000,\n",
      "     multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,\n",
      "     verbose=0):\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "     Class_1       0.63      0.30      0.41      1615\n",
      "     Class_2       0.65      0.86      0.74     13479\n",
      "     Class_3       0.51      0.33      0.40      6706\n",
      "     Class_4       0.72      0.14      0.23      2267\n",
      "     Class_5       0.94      0.96      0.95      2312\n",
      "     Class_6       0.93      0.93      0.93     11883\n",
      "     Class_7       0.71      0.61      0.65      2399\n",
      "     Class_8       0.84      0.92      0.88      7077\n",
      "     Class_9       0.79      0.86      0.83      4140\n",
      "\n",
      "   micro avg       0.76      0.76      0.76     51878\n",
      "   macro avg       0.75      0.66      0.67     51878\n",
      "weighted avg       0.75      0.76      0.74     51878\n",
      "\n",
      "\n",
      "Confusion matrix:\n",
      "[[  487    64    14     8     8   140    48   382   464]\n",
      " [   15 11626  1435    61    74    43   102    68    55]\n",
      " [    5  4209  2223    26     9    16   155    37    26]\n",
      " [    0  1356   386   308    17   114    62    17     7]\n",
      " [    3    71     4     0  2224     3     0     4     3]\n",
      " [   71   118    24    12     4 11006   166   270   212]\n",
      " [   57   260   193     7    18   171  1462   200    31]\n",
      " [   72    84    35     2     6   207    51  6494   126]\n",
      " [   69    73     6     5    10   158    23   218  3578]]\n"
     ]
    }
   ],
   "source": [
    "#3. 在校验集上测试，估计模型性能\n",
    "y_predict = SVC1.predict(X_val)\n",
    "\n",
    "print(\"accuracy is: \",accuracy_score(y_val, y_predict))\n",
    "\n",
    "print(\"Classification report for classifier %s:\\n%s\\n\"\n",
    "      % (SVC1, classification_report(y_val, y_predict)))\n",
    "print(\"Confusion matrix:\\n%s\" % confusion_matrix(y_val, y_predict))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用原始特征 + tfidf特征的线性SVM分类性能：accuracy is： 0.76430187459599219\n",
    "\n",
    "class_1,class_3和class_4分类效果不好。\n",
    "是因为这几类样本数目少？（class_6类的样本数目也不多）。后面采用类别权重试试\n",
    "(用class_weight='balanced'效果更差了)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 线性SVM正则参数调优"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "线性SVM LinearSVC的需要调整正则超参数包括C（正则系数，一般在log域（取log后的值）均匀设置候选参数）和正则函数penalty（L2/L1） \n",
    "\n",
    "采用交叉验证，网格搜索步骤与Logistic回归正则参数处理类似，在此略。\n",
    "\n",
    "这里我们用校验集（X_val、y_val）来估计模型性能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "#单组超参数情况，模型在训练集上训练，在校验集上的测试的测试性能\n",
    "def fit_grid_point_Linear(penalty, C, X_train, y_train, X_val, y_val):\n",
    "    \n",
    "    # 在训练集上训练SVC\n",
    "    SVC2 =  LinearSVC( penalty = penalty,C = C)\n",
    "    SVC2 = SVC2.fit(X_train, y_train)\n",
    "    \n",
    "    # 在校验集上返回accuracy\n",
    "    accuracy = SVC2.score(X_val, y_val)\n",
    "    \n",
    "    print(\"penalty = {} , C= {} : accuracy= {} \" .format(penalty, C, accuracy))\n",
    "    return accuracy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "penalty = l2 , C= 0.1 : accuracy= 0.750183121939936 \n",
      "penalty = l2 , C= 1.0 : accuracy= 0.7596283588418983 \n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\sklearn\\svm\\base.py:931: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.\n",
      "  \"the number of iterations.\", ConvergenceWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "penalty = l2 , C= 10.0 : accuracy= 0.7618836501021627 \n",
      "penalty = l2 , C= 100.0 : accuracy= 0.7600909826901576 \n",
      "penalty = l2 , C= 1000.0 : accuracy= 0.7277458652993561 \n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "No handles with labels found to put in legend.\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#需要调优的参数\n",
    "#SVM太慢，每次只调一个参数（这里只调C，penalty为‘l2'）\n",
    "C_s = np.logspace(-1, 3, 5)# logspace(a,b,N)把10的a次方到10的b次方区间分成N份  \n",
    "penalty_s = ['l2']\n",
    "\n",
    "accuracy_s = []\n",
    "for i, oneC in enumerate(C_s):\n",
    "    for j, penalty in enumerate(penalty_s):\n",
    "        tmp = fit_grid_point_Linear(penalty, oneC, X_train_part, y_train_part, X_val, y_val)\n",
    "        accuracy_s.append(tmp)\n",
    "\n",
    "x_axis = np.log10(C_s)\n",
    "for j, penalty in enumerate(penalty_s):\n",
    "    plt.plot(x_axis, np.array(accuracy_s), 'b-')\n",
    "    \n",
    "plt.legend()\n",
    "plt.xlabel( 'log(C)' )                                                                                                      \n",
    "plt.ylabel( 'accuracy' )\n",
    "#plt.savefig('SVM_Otto.png' )\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "#单组超参数情况，模型在训练集上训练，在校验集上的测试的测试性能\n",
    "def fit_grid_point_Linear2(penalty, C, X_train, y_train, X_val, y_val):\n",
    "    \n",
    "    # 在训练集上训练SVC\n",
    "    SVC2 =  LinearSVC( penalty = penalty,C = C)\n",
    "    SVC2 = SVC2.fit(X_train, y_train)\n",
    "    \n",
    "    # 在校验集上返回accuracy\n",
    "    #accuracy = SVC2.score(X_val, y_val)\n",
    "    score = cross_val_score(SVC2, X_train, y_train, cv=5)\n",
    "    \n",
    "    print(\"penalty = {} , C= {} : score= {} \" .format(penalty, C, score))\n",
    "    return score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "penalty = l2 , C= 0.1 : accuracy= [0.73389915 0.74837743 0.7495     0.75475475 0.75200401] \n",
      "penalty = l2 , C= 1.0 : accuracy= [0.74837743 0.76085871 0.764      0.76526527 0.76252505] \n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\sklearn\\svm\\base.py:931: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.\n",
      "  \"the number of iterations.\", ConvergenceWarning)\n",
      "D:\\Anaconda3\\lib\\site-packages\\sklearn\\svm\\base.py:931: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.\n",
      "  \"the number of iterations.\", ConvergenceWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "penalty = l2 , C= 10.0 : accuracy= [0.74937594 0.76335497 0.7675     0.77077077 0.77304609] \n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\sklearn\\svm\\base.py:931: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.\n",
      "  \"the number of iterations.\", ConvergenceWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "penalty = l2 , C= 100.0 : accuracy= [0.74687968 0.76035946 0.7635     0.76776777 0.77204409] \n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\sklearn\\svm\\base.py:931: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.\n",
      "  \"the number of iterations.\", ConvergenceWarning)\n",
      "No handles with labels found to put in legend.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "penalty = l2 , C= 1000.0 : accuracy= [0.67448827 0.67998003 0.73       0.74074074 0.73697395] \n"
     ]
    },
    {
     "data": {
      "image/png": "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rVoVawSPET3xdI/16aP3bSDvvafBBZs105ncrVtHtmndOp3N/f77Ogx89Gi99085RZ+xDz7QAR6VmWjFAhFJyAKcj7qefOuXAE+FKNscWAlketfPBj4C3gF+AYb59hU77ipgOjB93333lfLM7t0i330ncuedIv/3fyIZGSIgUru2yHnniTz/vMjvv0d3rgULRG67TaRePT1HZqb+BZHGjUUuuUTk1VdFVq8ueezatSIjRoh07y6SlaXHNG8ucuutIj/8IFJYGNefbVRyCgpEVq0SmTNHZPJkkXHjRC6+WO+7uXNLlv/+e5H69UUaNBCZMiW67/B4RJ57TqRqVT323XdF8vNFDjhAJDdX5L334vubyhvAdInmnR5NodIswAVBxOLJEGVvD9znFZrNQCt04uDbwBXhvu/www9PwGVMLMuWqQicd55InTr638jIULG4804Vj927ozvX5s0i99wj0rKlXxhAX/hduog88IDIL78Ef9mvXq0P08kn+4WlVSuRfv1Epk7Vh80wksXatSLVqolcemnw/QsW6P1ZtarI++9Hf97580UOO0zv76uu0ufv//5P7/nRo+Nje3kkHcTiKGBCwHoekBei7C/A0QHrRwKTA9YvAZ4O933lQSy2bRP5+GORG28U+cc//C/0pk1FLr9c5I03RNavj/58GzaIDBki0ratiHP+8zVoINKnj8iHH4ps3Rr82JUrRZ5+WuSEE/ytmDZtRAYMEPn5ZxMII7XceKNWdEK1plevFjniCL13n3km+vPu2qWVIOdE2rUT+eYbkVNO0fv/4YfjY3t5Ix3EIgtYCrQEcoCZwIFByrUDfsfbf+Ldlukt39C7Pgq4Ntz3paNYeDwiM2eKPPigyEknieTk6BWvUkWkWzeRRx7Rpna0L+Y9e7TpfeutIvvuW7QF0by5SN++IkuWhD4+P1/kiSdEOnf2i8s//iFyxx1qpwmEkS4sW6Zicf31ocv89ZfIGWfofZyXF9v9+/nnWknLzha5916R88/X8wwYUPmeg5SLhdrAaeiIqCXAQO+2wcBZAWXuBh4IcuwpwCxgNjAayAn3XekiFmvXiowZI9K7t8hee/lf5gceKHLLLSITJohs3x79+fLzRV58UW/mGjWKCsQ+++hDsnFj6OOXLxd59FGRo4/2H3fQQSJ33x3cJ2wY6cJll6mrac2a0GV271aXEmhf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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#需要调优的参数\n",
    "#SVM太慢，每次只调一个参数（这里只调C，penalty为‘l2'）\n",
    "C_s = np.logspace(-1, 3, 5)# logspace(a,b,N)把10的a次方到10的b次方区间分成N份  \n",
    "penalty_s = ['l2']\n",
    "\n",
    "score_s = []\n",
    "for i, oneC in enumerate(C_s):\n",
    "    for j, penalty in enumerate(penalty_s):\n",
    "        tmp = fit_grid_point_Linear2(penalty, oneC, X_train_part, y_train_part, X_val, y_val)\n",
    "        score_s.append(tmp)\n",
    "\n",
    "x_axis = np.log10(C_s)\n",
    "for j, penalty in enumerate(penalty_s):\n",
    "    plt.plot(x_axis, np.array(score_s), 'b-')\n",
    "    \n",
    "plt.legend()\n",
    "plt.xlabel( 'log(C)' )                                                                                                      \n",
    "plt.ylabel( 'score' )\n",
    "#plt.savefig('SVM_Otto.png' )\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10.0\n"
     ]
    }
   ],
   "source": [
    "### 最佳超参数\n",
    "index = np.argmax(accuracy_s, axis=None)\n",
    "Best_C = C_s[ index ]\n",
    "\n",
    "print(Best_C)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## 找到最佳参数后，用全体训练数据训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# SVC训练SVC，支持概率输出\n",
    "Best_C = 100\n",
    "\n",
    "SVC3 = LinearSVC(C = Best_C)\n",
    "SVC3.fit(X_train, y_train)\n",
    "\n",
    "#保持模型，用于后续测试\n",
    "import cPickle\n",
    "cPickle.dump(SVC3, open(\"Otto_LinearSVC.pkl\", 'wb'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
